// 引用express框架
const express = require('express');
const admin = express.Router();
const path = require('path')
// const {user}=require('../../../model/user');
const {user, validateUser} = require('../../modle/user')
const {article} = require('../../modle/article')

// 引入密码加密模块
const bcrypt = require('bcryptjs');

// 引入formidable第三方模块 获取二进制数据
const formidable = require('formidable')

// // 引入Joi验证模块
// const Joi=require('joi');

// 导入mongoose-sex-page分页第三方模块
const pagination = require('mongoose-sex-page')

// 登录页面渲染
admin.get('/login', (req, res) => {
    res.render('admin/login')
})
// 登录
// admin.post('/login',async (req,res)=>{
//    // 接受请求参数
//    const {email,password}=req.body;
//    // 表单验证
//    if(email.trim().length==0||password.trim().length==0){
//       return res.status(400).render('admin/error',{msg:"邮箱或密码错误"})
//    }
//    // 根据邮箱地址查询用户信息 如果不存在则返回空
//    let User=await user.findOne({email:email});
//    if(User){
//       // 将客户端传递过来的密码和用户信息中的密码进行比对
//       let isValid=await bcrypt.compare(password,User.password);
//       console.log(isValid);
//       if(isValid){
//          // 将用户名存储在请求对象中
//          req.session.username=User.username;
//          console.log(req.session.username);
//
//          // 以下方式，可通过模板访问到
//          req.app.locals.userInfo=User;
//          // req.app.locals.userInfo=User.role;
//          // 判断用户身份，重定向到后台或前台
//          if(User.role=='admin'){
//             res.redirect('/admin/user');
//          }else {
//             res.redirect('/home');
//          }
//       }else {
//          return res.status(400).render('admin/error',{msg:"邮箱或密码错误"})
//       }
//    }else {
//      return res.status(400).render('admin/error',{msg:"邮箱或密码错误"})
//    }
// })

admin.post('/login', require('./login'))


// 退出登录
admin.get('/logout', (req, res) => {
    // 删除session
    req.session.destroy(function () {
        // 清除模板中的用户信息
        req.app.locals.userInfo = null
        // 删除cookie
        res.clearCookie('connect.sid');
        // 重定向到用户登录页面
        res.redirect('/admin/login')
    })
})

// 用户列表页面渲染
admin.get('/user', async (req, res) => {
    req.app.locals.currentLink = 'user';//用户管理页面
    // 接受客户端传递过来的当前页参数
    const page = req.query.page || 1;
    // 每一页的数据条数
    const pageSize = 5;
    // 查询用户列表的总数
    //DeprecationWarning: collection.count is deprecated, and will be removed in a future version. Use Collection.countDocuments or Collection.estimatedDocumentCount instead
    // 已弃用
    // const count=await user.count();
    const count = await user.countDocuments({});
    // 总页数
    const total = Math.ceil(count / pageSize);
    // 页码对应的数据开始查询的位置
    // 数据开始查询位置=（当前页-1）*每页显示条数
    const start = (page - 1) * pageSize;
    // 查询用户分页列表 limit()查询的数量 skip()跳过多少条数据
    const Users = await user.find({}).limit(pageSize).skip(start);
    res.render('admin/user', {
        Users: Users,
        page: page,
        total: total,
        count: count
    })
})

// 用户编辑和修改页面渲染
admin.get('/user-edit', async (req, res) => {
    req.app.locals.currentLink = 'user';//用户管理页面
    // 获取到地址栏的ID
    const {message, id} = req.query;
    if (id) {//修改
        const User = await user.findOne({_id: id})
        res.render('admin/user-edit', {
            message: message,
            User: User,
            link: '/admin/user-modify?id=' + id,
            botton: '修改'
        })
    } else {//添加
        res.render('admin/user-edit', {
            message: message,
            link: '/admin/user-edit',
            botton: '添加'
        })
    }
})

// 用户添加
admin.post('/user-edit', async (req, res, next) => {
    try {
        // 实时验证
        await validateUser(req.body);
    } catch (e) {
        // 重定向到用户添加页面
        // e.message Joi第三方模块验证的错误信息
        // return res.redirect('/admin/user-edit?message='+e.message)
        // 统一处理错误信息
        return next(JSON.stringify({path: '/admin/user-edit', message: e.message}))
    }
    // 根据邮箱地址查询用户是否存在
    const User = await user.findOne({email: req.body.email});
    if (User) {
        // return res.redirect('/admin/user-edit?message='+'邮箱地址已经被占用了')
        return next(JSON.stringify({path: '/admin/user-edit', message: "邮箱地址已经被占用了"}))
    }
    // 对密码进行加密处理
    const salt = await bcrypt.genSalt(10);
    // 加密
    const password = await bcrypt.hash(req.body.password, salt);
    // 将加密的密码替换
    req.body.password = password;
    // 将用户提交的信息添加到数据中
    await user.create(req.body);
    res.redirect('/admin/user')

})

// 用户修改
admin.post('/user-modify', async (req, res, next) => {
    const id = req.query.id;//修改的用户ID
    const User = await user.findOne({_id: id});

    if (!req.body.password) {
        // return res.send('请输入密码')
        return next(JSON.stringify({path: '/admin/user-edit', message: "请输入密码", id: id}))
    }
    console.log(req.body.password);
    // 密码比对
    const isValid = await bcrypt.compare(req.body.password, User.password);
    console.log(isValid);
    if (isValid) {
        // 将用户信息更新到数据库中，不修改密码
        //  await user.updateOne({_id:id},{
        //    username:username,
        //    email:email,
        //    role:role,
        //    state:state,
        // })
        delete req.body.password
        console.log(req.body);
        await user.updateOne({_id: id}, req.body)
        res.redirect('/admin/user')
    } else {
        // 统一处理错误信息，需要传递ID，避免密码错误重定向将表单置空的体验问题
        return next(JSON.stringify({path: '/admin/user-edit', message: "密码错误，无法修改", id: id}))
    }
})

// 用户删除
admin.get('/delete', async (req, res) => {
    const {id} = req.query;
    await user.findOneAndDelete({_id: id});
    res.redirect('/admin/user')
})


// 文章列表页面渲染
admin.get('/article', async (req, res) => {
    req.app.locals.currentLink = 'article';//文章管理页面，用以区分侧边栏导航高亮
    // 查询文章列表 多集合联合查询 populate('author')
    // const Article=await article.find({}).populate('author')
    /*
    * page 当前页
    * size   每页显示的条数
    * display 客户端显示的页面数量
    * exec 向数据库发起查询请求
    * */
    // 点击页码渲染页面
    const page = req.query.page;

    // console.log(await article.find({}).populate('author'));
    let Article = await pagination(article).find({}).page(page).size(2).display(3).populate('author').exec();

    // Maximum call stack size exceeded 报错大概意思是mongoose返回文档对象太过庞大，或者是populate方法导致的
    // 解决方案：https://www.cnblogs.com/dreamer-lin/p/13674413.html

    // console.log(Article);
    let dataStr = JSON.stringify(Article)
    let Articles = JSON.parse(dataStr)

    // console.log(Articles);
    // return res.send(Article)
    res.render('admin/article', {
        Article: Articles
    })
})

// 文章编辑
admin.get('/article-edit', async (req, res) => {
    req.app.locals.currentLink = 'article';//文章管理页面
    const id = req.query.id;
    const Article = await article.findOne({_id: id});
    // console.log(Article);
    if (id) {
        res.render('admin/article-edit', {
            link: '/admin/article-modify?id=' + id,
            botton: '修改',
            Article
        })
    } else {
        res.render('admin/article-edit', {
            link: '/admin/article-add',
            botton: '添加'
        })
    }
})

// 文章添加
admin.post('/article-add', (req, res) => {
    // 创建表单解析对象
    const form = new formidable.IncomingForm();
    // 配置上传文件的存放位置
    form.uploadDir = path.join(__dirname, '../', '../', 'public', 'uploads');
    // 保留上传文件的后缀
    form.keepExtensions = true;
    // 解析表单
    form.parse(req, async (err, fields, files) => {
        // err错误对象
        // fields保存的表单数据
        // files保存的上传文件
        const {title, author, publishDate, content} = fields;
        // if(!title&&!author&&!publishDate&&!content) return res.status(400).render('admin/error',{msg:"不符合规范"})

        console.log(files);
        console.log(files.cover.path.split('public')[1]);
        const cover = files.cover.path.split('public')[1] || ''
        await article.create({
            title,
            author,
            publishDate,
            cover,
            content
        }).then(() => {
            // res.send(files.cover.path.split('public')[1])
            res.redirect('/admin/article')
        }).catch(error => {
            // 获取自定义错误信息对象
            const err = error.errors;
            let message = '';
            for (let attr in err) {
                console.log(err[attr]['message']);
                message = err[attr]['message'];
            }
            console.log(message);
            res.render('admin/article-edit', {
                link: '/admin/article-add',
                botton: '添加',
                message: message
            })
        })

    })
})

// 文章修改
admin.post('/article-modify', (req, res) => {
    const id = req.query.id;
    // 创建表单解析对象
    const form = new formidable.IncomingForm();
    // 配置上传文件的位置
    form.uploadDir = path.join(__dirname, '../', '../', 'public', 'uploads');
    // 保存上传文件的后缀
    form.keepExtensions = true;
    // 解析表单
    form.parse(req, async (err, fields, files) => {
        const {title, author, publishDate, content} = fields;
        await article.findByIdAndUpdate({_id: id}, {
            title,
            author,
            publishDate,
            cover: files.cover.path.split('public')[1],
            content
        });
        res.redirect('/admin/article')
    })


})

// 文章删除
admin.get('/article-delete', async (req, res) => {
    const id = req.query.id;
    // console.log(id);
    await article.findOneAndDelete({_id: id});
    res.redirect('/admin/article')
})


// 将路由对象作为模块成员进行导出
module.exports = admin
